package com.ssm.util;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect  
public class Aop {

	 private long start;
	    private long end;
	    private static Logger logger = Logger.getLogger(Aop.class);
	    @Pointcut("execution(* com.ssm.controller.*.*(..))")
	    public void pointCut_(){
	    }

	    @Before(value="pointCut_()")
	    public void beforeMethod(JoinPoint joinPoint){
	        String methodName = joinPoint.getSignature().getName();
	        Object args = Arrays.asList(joinPoint.getArgs());
	        start = System.currentTimeMillis();
	        logger.info("The method:"+methodName +" begins with "+ args);
	    }


	    /**
	     * 	后置通知：在目标方法之后(无论是否发生异常)，执行的通知，
	     在后置通知中还不能访问目标方法执行的结果。执行结果须在返回通知中访问。
	     * @Title: afterMethod
	     * @Description: TODO(这里用一句话描述这个方法的作用)
	     * @param @param joinPoint    参数
	     * @return void    返回类型
	     * @throws
	     */
	    @After(value="pointCut_()")
	    public void afterMethod(JoinPoint joinPoint){
	        String methodName = joinPoint.getSignature().getName();
	        end = System.currentTimeMillis();
	        logger.info("The method:"+ methodName+" ends"+"执行业务方法共计：" + (end - start) + "毫秒");
	    }
	    /**
	     * 返回通知：在目标方法正常结束执行后的通知
	     * @Title: afterRunningMethod
	     * @Description: TODO(这里用一句话描述这个方法的作用)
	     * @param @param joinPoint
	     * @param @param result    参数
	     * @return void    返回类型
	     * @throws
	     */
	    @AfterReturning(value="pointCut_()",returning="result")
	    public void afterRunningMethod(JoinPoint joinPoint , Object result){
	        String methodName = joinPoint.getSignature().getName();
	        logger.info("The method:"+ methodName+" ends with the Result "+ result);
	    }
	    /**
	     * 环绕通知
	     * @Title: aroundAdvice
	     * @Description: TODO(这里用一句话描述这个方法的作用)
	     * @param @param proceedingJoinPoint
	     * @param @return
	     * @param @throws Throwable    参数
	     * @return Object    返回类型
	     * @throws
	     */
	    //@Around(value="pointCut_()")
	    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
	        Object result = null;
	        String  methodName = proceedingJoinPoint.getSignature().getName();
	        Object args = Arrays.asList(proceedingJoinPoint.getArgs());
	        try {
	            logger.info("Arround:The method "+methodName +" begins with "+args);
	            long start = System.currentTimeMillis();
	            result = proceedingJoinPoint.proceed();
	            long end = System.currentTimeMillis();
	            logger.info("Arround:The method "+ methodName+" ends"+","+"执行业务方法共计：" + (end - start) + "毫秒。");
	        } catch(Exception e){
	            e.printStackTrace();
	            logger.info("Arround:异常监控 "+ methodName+"occurs exception:"+e);
	            throw new RuntimeException(e);
	        }
	        logger.info("Arround:The method "+ methodName+" ends with the Result "+ result);
	        return result;
	    }
	    /**
	     * 异常通知
	     * @Title: throwingAdvice
	     * @Description: TODO(这里用一句话描述这个方法的作用)
	     * @param @param joinPoint
	     * @param @param e    参数
	     * @return void    返回类型
	     * @throws
	     */

	    @AfterThrowing(value="pointCut_()",throwing = "e")
	    public void throwingAdvice(JoinPoint joinPoint, Exception e) {
	        String methodName = joinPoint.getSignature().getName();
	        logger.info("异常监控:" + methodName + " occurs exception: " + e);
	    }

}
